package com.sneakxy.actions.code;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

/**
 * @author 潜行的虚影
 * @see
 */
public class ClassType implements Type {

	private String name;
	
	private String packageName;
	
	private List<String> generics = new ArrayList<>();
	
	private boolean hasPackage = false;
	
	public ClassType(String fullName) {
		this.name = StringUtils.trimToEmpty(fullName);
		if(StringUtils.isBlank(this.name)) {
			throw new NullPointerException("fullName could not be null.");
		}
		this.init();
	}

	public ClassType(Class<?> type) {
		if(type == null) {
			throw new NullPointerException("type could not be null.");
		}
		this.name = type.getName();
		this.init();
	}

	private void init() {
		if(StringUtils.indexOf(this.name, ".") > -1) {
			int lastIndex = StringUtils.lastIndexOf(this.name, ".");
			this.packageName = StringUtils.substring(name, 0, lastIndex);
			if(StringUtils.equals(this.packageName, "java.lang")) {
				this.packageName = null;
			}
			this.name = StringUtils.substring(this.name, lastIndex + 1);
		}
	}
	
	public void addGenerics(String name) {
		this.generics.add(name);
	}
	
	public String toGenericsString() {
		StringBuilder s = new StringBuilder();
		if(!this.generics.isEmpty()) {
			s.append("<");
			Iterator<String> it = this.generics.iterator();
			while(it.hasNext()) {
				s.append(it.next());
				if(it.hasNext()) {
					s.append(", ");
				}
			}
			s.append(">");
		}
		return s.toString();
	}
	
	public String toString(boolean isNotImport) {
		StringBuilder s = new StringBuilder();
		if(!isNotImport || (hasPackage && this.hasImportPackage())) {
			s.append(this.getImportPackage()).append(".");
		}
		s.append(this.getTypeName());
		if(isNotImport) {
			s.append(this.toGenericsString());
		}
		return s.toString();
	}
	
	public String getTypeName() {
		return name;
	}
	
	public String getImportPackage() {
		return this.packageName;
	}
	
	public boolean hasImportPackage() {
		return StringUtils.isNotBlank(packageName);
	}

	@Override
	public int hashCode() {
		return new HashCodeBuilder().append(this.getTypeName()).toHashCode();
	}

	public boolean isHasPackage() {
		return hasPackage;
	}

	public void setHasPackage(boolean hasPackage) {
		this.hasPackage = hasPackage;
	}

	@Override
	public boolean equals(Object obj) {
		if(obj == null) {
			return false;
		}
		if(obj == this) {
			return true;
		}
		if(!(obj instanceof Type)) {
			return false;
		}
		Type type = (Type) obj ;
		return new EqualsBuilder().append(type.getTypeName(), this.getTypeName()).isEquals();
	}
	
}